package org.jeecg.modules.monitoring.j_monitoring.controller;

import java.util.*;
import java.util.stream.Collectors;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import com.xkcoding.http.util.StringUtil;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.message.handle.impl.EmailSendMsgHandle;
import org.jeecg.modules.monitoring.j_monitoring.entity.MDailyInspection;
import org.jeecg.modules.monitoring.j_monitoring.entity.MDailyInspectionDTO;
import org.jeecg.modules.monitoring.j_monitoring.entity.MDailyInspectionFile;
import org.jeecg.modules.monitoring.j_monitoring.entity.MMachineRoom;
import org.jeecg.modules.monitoring.j_monitoring.service.IMDailyInspectionService;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;

import org.jeecg.modules.monitoring.j_monitoring.service.IMMachineRoomService;
import org.jeecg.modules.monitoring.j_monitoring.vo.MDailyInspectionVo;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.service.ISysUserService;
import org.jeecgframework.core.util.ApplicationContextUtil;
import org.jeecgframework.poi.excel.ExcelImportUtil;
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.excel.entity.ImportParams;
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
import org.jeecg.common.system.base.controller.JeecgController;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;
import com.alibaba.fastjson.JSON;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.jeecg.common.aspect.annotation.AutoLog;

/**
 * @Description: 日常巡检
 * @Author: xiaoyq
 * @Date: 2023-10-10
 * @Version: V1.0
 */
@Api(tags = "日常巡检")
@RestController
@RequestMapping("/j_monitoring/mDailyInspection")
@Slf4j
public class MDailyInspectionController extends JeecgController<MDailyInspection, IMDailyInspectionService> {
    @Autowired
    private IMMachineRoomService roomService;
    /**
     * 分页列表查询
     *
     * @param mDailyInspection
     * @param pageNo
     * @param pageSize
     * @param req
     * @return
     */
    //@AutoLog(value = "日常巡检-分页列表查询")
    @RequiresPermissions("日常巡检:查询")
    @ApiOperation(value = "日常巡检-分页列表查询", notes = "日常巡检-分页列表查询")
    @GetMapping(value = "/list")
    public Result<IPage<MDailyInspection>> queryPageList(MDailyInspection mDailyInspection,
                                                         @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                         @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                                         HttpServletRequest req) {
        QueryWrapper<MDailyInspection> queryWrapper = QueryGenerator.initQueryWrapper(mDailyInspection, req.getParameterMap());
        Page<MDailyInspection> page = new Page<MDailyInspection>(pageNo, pageSize);
        IPage<MDailyInspection> pageList = service.page(page, queryWrapper);
        return Result.OK(pageList);
    }

    /**
     * 添加
     *
     * @param mDailyInspection
     * @return
     */
    @AutoLog(value = "日常巡检-添加")
    @ApiOperation(value = "日常巡检-添加", notes = "日常巡检-添加")
    @RequiresPermissions("日常巡检:排班")
    @PostMapping(value = "/add")
    public Result<String> add(@RequestBody MDailyInspection mDailyInspection) {

        LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        List<MMachineRoom> roomList = roomService.getAllList();
        for (MMachineRoom room : roomList) {
            MDailyInspection inspection = new MDailyInspection();

            BeanUtils.copyProperties(mDailyInspection, inspection);
            inspection.setMachineRoomName(room.getName());
            inspection.setMachineRoomId(room.getId());
            inspection.setCreateUserName(loginUser.getUsername());
            inspection.setCreateUserName(loginUser.getId());
            service.save(inspection);

        }
        return Result.OK("添加成功！");
    }

    /**
     * 批量添加
     *
     * @param dailyInspectionVo
     * @return
     */
    @AutoLog(value = "日常巡检-巡检排班")
    @ApiOperation(value = "日常巡检-巡检排班", notes = "日常巡检-巡检排班")
    @PostMapping(value = "/batchAdd")
    @RequiresPermissions("日常巡检:排班")
    public Result<String> batchAdd(@RequestBody MDailyInspectionVo dailyInspectionVo) {

        LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();

        List<MDailyInspection> dataList = new ArrayList<>();
        List<MMachineRoom> roomList = roomService.getAllList();
        Date nextDay = dailyInspectionVo.getStartDate(),start;
        Calendar cld = Calendar.getInstance();
        cld.setTime(dailyInspectionVo.getEndDate());
        cld.add(Calendar.DATE, 1);
        dailyInspectionVo.setEndDate(cld.getTime());
        int stepDay = dailyInspectionVo.getModel()==1? dailyInspectionVo.getDay():1;
        QueryWrapper<MDailyInspection> queryWrapper = new QueryWrapper<>();
        MDailyInspection inspection;
        for (MMachineRoom room : roomList) {
            //当明天不在结束时间之前是终止循环
            start = dailyInspectionVo.getStartDate();
            nextDay = start;
            while(nextDay.before(dailyInspectionVo.getEndDate())){
                queryWrapper.clear();
                queryWrapper.lambda().eq(MDailyInspection::getInspectionDate,start).eq(MDailyInspection::getMachineRoomId,room.getId());
                inspection = service.getOne(queryWrapper);
                if(inspection==null){
                    inspection = new MDailyInspection();
                }
                inspection.setMachineRoomName(room.getName());
                inspection.setMachineRoomId(room.getId());
                inspection.setInspectionDate(start);
                inspection.setPersonnel(dailyInspectionVo.getPersonnel());
                inspection.setPersonnelId(dailyInspectionVo.getPersonnelId());
                inspection.setCreateUserName(loginUser.getUsername());
                inspection.setCreateUserName(loginUser.getId());
                dataList.add(inspection);

                cld.setTime(start);
                cld.add(Calendar.DATE, stepDay);
                start = cld.getTime();
                nextDay = start;
            }

        }
        boolean isOk = service.saveOrUpdateBatch(dataList);
        if(isOk){
            return Result.OK("巡检排班成功！");
        }
        else{
            return Result.error("巡检排班失败！");
        }
    }

    /**
     * 编辑
     *
     * @param mDailyInspection
     * @return
     */
    @AutoLog(value = "日常巡检-编辑")
    @ApiOperation(value = "日常巡检-编辑", notes = "日常巡检-编辑")
    @RequiresPermissions("日常巡检:编辑")
    @RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
    public Result<String> edit(@RequestBody MDailyInspection mDailyInspection) {
        mDailyInspection.setRecordDate(new Date());
        service.updateById(mDailyInspection);
        return Result.OK("编辑成功!");
    }

    /**
     * 编辑
     *
     * @param dailyInspection
     * @return
     */
    @AutoLog(value = "日常巡检-发送邮件")
    @ApiOperation(value = "日常巡检-发送邮件", notes = "日常巡检-发送邮件")
    @RequiresPermissions("日常巡检:排班")
    @RequestMapping(value = "/sendEmail", method = {RequestMethod.POST})
    public Result<String> sendEmail(@RequestBody MDailyInspectionVo dailyInspection) {

        EmailSendMsgHandle emailHandle=new EmailSendMsgHandle();
        List<String> idList = Arrays.asList((dailyInspection.getPersonnelId()!=null? dailyInspection.getPersonnelId():"").split(","));
        List<SysUser> userList = null;
        if(idList.size()>0){
            ISysUserService userService = ApplicationContextUtil.getContext().getBean(ISysUserService.class);
            userList = userService.listByIds(idList);
        }
        if(userList!=null && userList.size()>0){
            SysUser user;
            idList = new ArrayList<>();
            for (int i = 0; i < userList.size(); i++) {
                user = userList.get(i);
                if(StringUtils.isNotBlank(user.getEmail())){
                    idList.add(user.getEmail().trim());
                }
            }
            if(idList.size()==0){
                return Result.error("排班人员未设置电子邮箱!");
            }
            if(idList.size()>0){
                String email = StringUtils.join(idList,",");
                String title = "中国海油-数据中心巡检安排";
                StringBuilder msg = new StringBuilder();
                msg.append(dailyInspection.getPersonnel()+":\n\n");
                msg.append("    你们好，你们的巡检安排从" + DateUtils.formatDate(dailyInspection.getStartDate(),"yyyy-MM-dd")+"到"+DateUtils.formatDate(dailyInspection.getEndDate(),"yyyy-MM-dd"));
                if(dailyInspection.getModel()==1){
                    msg.append("每" + dailyInspection.getDay()+"天一轮。");
                }
                emailHandle.sendMsg(email, title, msg.toString());
            }
        }

        return Result.OK("邮件发送成功!");
    }

    /**
     * 通过id删除
     *
     * @param id
     * @return
     */
    @AutoLog(value = "日常巡检-通过id删除")
    @ApiOperation(value = "日常巡检-通过id删除", notes = "日常巡检-通过id删除")
    @RequiresPermissions("日常巡检:删除")
    @DeleteMapping(value = "/delete")
    public Result<String> delete(@RequestParam(name = "id", required = true) String id) {
        service.removeById(id);
        return Result.OK("删除成功!");
    }

    /**
     * 批量删除
     *
     * @param ids
     * @return
     */
    @AutoLog(value = "日常巡检-批量删除")
    @ApiOperation(value = "日常巡检-批量删除", notes = "日常巡检-批量删除")
    @RequiresPermissions("日常巡检:批量删除")
    @DeleteMapping(value = "/deleteBatch")
    public Result<String> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
        this.service.removeByIds(Arrays.asList(ids.split(",")));
        return Result.OK("批量删除成功!");
    }

    /**
     * 通过id查询
     *
     * @param id
     * @return
     */
    //@AutoLog(value = "日常巡检-通过id查询")
    @ApiOperation(value = "日常巡检-通过id查询", notes = "日常巡检-通过id查询")
    @GetMapping(value = "/queryById")
    @RequiresPermissions("日常巡检:查询")
    public Result<MDailyInspection> queryById(@RequestParam(name = "id", required = true) String id) {
        MDailyInspection mDailyInspection = service.getById(id);
        //mDailyInspection.setUploadFileList(service.getFileListById(id));
        if (mDailyInspection == null) {
            return Result.error("未找到对应数据");
        }
        return Result.OK(mDailyInspection);
    }

    /**
     * 通过id查询附件列表
     *
     * @param id
     * @return
     */
    @ApiOperation(value = "日常巡检-通过id查询附件列表", notes = "日常巡检-通过id附件列表")
    @GetMapping(value = "/queryImagesById")
    @RequiresPermissions("日常巡检:查询")
    public Result<?> queryImagesById(@RequestParam(name = "id", required = true) String id) {
        List<MDailyInspectionFile> imageList = service.getImageList(id);
        if (imageList == null) {
            return Result.error("未找到对应数据");
        }
        return Result.OK(imageList);
    }

    /**
     * 导出excel
     *
     * @param request
     * @param mDailyInspection
     */
    @RequiresPermissions("日常巡检:导出")
    @RequestMapping(value = "/exportXls", method = RequestMethod.GET)
    @ApiOperation(value="日常巡检-导出", notes="日常巡检-导出")
    public ModelAndView exportXls(HttpServletRequest request, MDailyInspection mDailyInspection) {
        return super.exportXls(request, mDailyInspection, MDailyInspection.class, "日常巡检");
    }

    /**
     * 通过excel导入数据
     *
     * @param request
     * @param response
     * @return
     */
    @RequiresPermissions("日常巡检:导入")
    @ApiOperation(value="日常巡检-导入", notes="日常巡检-导入")
    @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
        return super.importExcel(request, response, MDailyInspection.class);
    }


    /**
     * 根据日期获取数据
     *
     * @return
     */
    @RequiresPermissions("日常巡检:查询")
    @RequestMapping(value = "/getListByDate", method = RequestMethod.GET)
    public Result<Map> getListByDate(String date) {

        //获取月份前15天到后15天的日期
        String startTime = DateUtils.dateAdd(date + "-01", -15);

        String endTime = DateUtils.dateAdd(DateUtils.monthAdd(date + "-01", +1), 15);

        List<MDailyInspection> inspectionList = service.getListByTime(startTime, endTime);

        Map<String, List<MDailyInspection>> result = new HashMap<>();
        for (MDailyInspection inspection : inspectionList) {
            inspection.setWarningType(this.getWarningType(inspection));
            String key = DateUtils.formatDate(inspection.getInspectionDate());
            if (result.get(key) == null || result.get(key).size() == 0) {
                List<MDailyInspection> keyList = new ArrayList<>();
                keyList.add(inspection);
                result.put(key, keyList);
            } else {
                List<MDailyInspection> keyList = result.get(key);
                keyList.add(inspection);
                result.put(key, keyList);
            }
        }

        return Result.ok(result);
    }

    private String getWarningType(MDailyInspection inspection) {
        if (
                StringUtil.isEmpty(inspection.getRecordTime())
        ) {
            return "error";
        }
        return "success";
    }


    @RequestMapping(value = "/getWeekDay", method = RequestMethod.GET)
    public Result<Map> getWeekDay(String date) {
        Map<String,String> map = new HashMap<>();
        try {
            String year = date.substring(0,4);
            String week = DateUtils.getWeek(date);
            map.put("start",DateUtils.getFirstDayOfWeek(new Integer(year),new Integer(week)));
            map.put("end",DateUtils.getLastDayOfWeek(new Integer(year),new Integer(week)));
        }catch (Exception e){

        }

        return Result.ok(map);
    }


    //查询登陆人需要处理的巡检任务
    @RequestMapping(value = "/getTodayInspection", method = RequestMethod.GET)
    @RequiresPermissions("日常巡检:查询")
    public Result getTodayInspection() {
        LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        String userId = loginUser.getId();
        return Result.ok(service.getTodayInspection(userId));
    }

    //查询登陆人需要处理的巡检任务
    @RequestMapping(value = "/saveTodayInspection", method = RequestMethod.POST)
    @RequiresPermissions("日常巡检:查询")
    public Result saveTodayInspection(@RequestBody MDailyInspectionDTO[] dataList) {

        return Result.ok(service.saveTodayInspection(dataList));
    }

    //查询登陆人需要处理的巡检任务
    @RequestMapping(value = "/getPlanInspection", method = RequestMethod.GET)
    @RequiresPermissions("日常巡检:查询")
    public Result getPlanInspection() {
        LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        String userId = loginUser.getId();
        return Result.ok(service.getPlanInspection(userId));
    }

}
